home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <workbench/workbench.h>
- #include <workbench/icon.h>
- #include <clib/macros.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- // #include <functions.h>
-
- #include <proto/dos.h>
- #include <proto/wb.h>
- #include <proto/icon.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <clib/alib_protos.h>
-
- // #include "PatMatch.h"
- #include "Monger.h"
-
- #define MAXCHARS 120
-
- char file_pat_parsed[ MAXCHARS * 2 ];
- char old_tool_pat_parsed[ MAXCHARS * 2 ];
- char tmp_oldimagename[ MAXCHARS ];
- char tmp_newimagename[ MAXCHARS ];
-
- struct DiskObject *newicon = NULL;
- struct DiskObject *oldimage = NULL;
- struct DiskObject *newimage = NULL;
-
- /**********************************************************************/
- /******* Interrupt Control Section *******************************/
-
- BOOL control_c_hit = FALSE;
-
- void __regargs _CXBRK( void );
-
- void __regargs _CXBRK( void )
- {
- control_c_hit = TRUE;
- }
-
- int stop_check( void )
- {
- chkabort();
- return control_c_hit;
- }
-
-
- /**********************************************************************/
- /******* Image Recoloring Section *******************************/
-
- typedef struct FixImage_
- {
- struct Image new_image;
- struct Image *org_image;
- struct BitMap bm;
- struct RastPort rp;
- } FixImage_t;
-
- static void free_fix_image( FixImage_t *fi )
- {
- if ( fi->bm.Planes[0] )
- FreeMem( fi->bm.Planes[0], RASSIZE(fi->new_image.Width,fi->new_image.Height * fi->new_image.Depth) );
- FreeMem( fi, sizeof(*fi) );
- }
-
- static FixImage_t *fix_image_pens( struct Image *i )
- {
- FixImage_t *fi;
- struct Image *old_NextImage;
- WORD old_LeftEdge;
- WORD old_TopEdge;
- LONG j,k,l;
-
- if ( (!i) || (i->Depth < 2) ) return NULL;
-
- if ( (fi = AllocMem( sizeof( FixImage_t ), MEMF_ANY | MEMF_CLEAR )) )
- {
- fi->org_image = i;
-
- InitBitMap ( &fi->bm, MIN(i->Depth,8), i->Width, i->Height );
- InitRastPort( &fi->rp );
- fi->rp.BitMap = &fi->bm;
-
- fi->bm.Planes[0] = (PLANEPTR)AllocRaster( i->Width, MIN(i->Depth,8)*i->Height);
- if ( fi->bm.Planes[0] == NULL )
- {
- free_fix_image( fi );
- return NULL;
- }
-
- fi->new_image.LeftEdge = i->LeftEdge;
- fi->new_image.TopEdge = i->TopEdge;
- fi->new_image.Width = i->Width;
- fi->new_image.Height = i->Height;
- fi->new_image.Depth = MIN(i->Depth,8);
- fi->new_image.ImageData = (UWORD *)fi->bm.Planes[0];
- fi->new_image.PlanePick = (UBYTE)((~(0x0ff << MIN(i->Depth,8)))&(0xff));
- fi->new_image.PlaneOnOff = 0;
- fi->new_image.NextImage = NULL;
-
- for (j=1; j<MIN(i->Depth,8); j++ )
- fi->bm.Planes[j] = &(fi->bm.Planes[0][(j*RASSIZE(i->Width,i->Height))]);
-
- old_NextImage= i->NextImage;
- old_LeftEdge = i->LeftEdge;
- old_TopEdge = i->TopEdge;
-
- i->NextImage = NULL;
- i->LeftEdge = 0;
- i->TopEdge = 0;
-
- DrawImage(&fi->rp,i,0,0);
-
- i->NextImage = old_NextImage;
- i->LeftEdge = old_LeftEdge;
- i->TopEdge = old_TopEdge;
-
- for (j=0; j<i->Width; j++)
- for (k=0; k<i->Height; k++)
- {
- l = ReadPixel(&fi->rp,j,k);
- SetAPen( &fi->rp, l==1?2:l==2?1:l );
- WritePixel( &fi->rp,j,k);
- }
- }
- return fi;
- }
-
- static FixImage_t *fi0 = NULL;
- static FixImage_t *fi1 = NULL;
-
- void recolor( struct DiskObject *DO )
- {
- fi0 = fix_image_pens( DO->do_Gadget.GadgetRender );
- fi1 = fix_image_pens( DO->do_Gadget.SelectRender );
- if ( fi0 )
- DO->do_Gadget.GadgetRender = (APTR)&fi0->new_image;
- if ( fi1 )
- DO->do_Gadget.SelectRender = (APTR)&fi1->new_image;
- }
-
- void decolor( struct DiskObject *DO )
- {
- if ( fi0 )
- {
- DO->do_Gadget.GadgetRender = (APTR)fi0->org_image;
- free_fix_image( fi0 );
- fi0 = NULL;
- }
- if ( fi1 )
- {
- DO->do_Gadget.SelectRender = (APTR)fi1->org_image;
- free_fix_image( fi1 );
- fi1 = NULL;
- }
- }
-
- /**********************************************************************/
- /**********************************************************************/
-
-
- BOOL scan_setup( void )
- {
- BOOL retcode = TRUE;
-
- if ( parms.new_icon && ( parms.disks || parms.drawers ||
- parms.tools || parms.projects ||
- parms.garbage || parms.unsnapshot ||
- parms.recolor || parms.new_image ||
- parms.new_tool || parms.new_stack ) )
- {
- printf("Error: NEWICON not allowed with DISKS, DRAWERS, "
- "PROJECTS, TOOLS, GARBAGE, UNSNAPSHOT, "
- "RECOLOR, NEWIMAGE, NEWTOOL, or NEWSTACK.\n");
- retcode = FALSE;
- }
-
- if ( parms.new_stack && ( *parms.new_stack < 400 ) )
- {
- printf("Error: NEWSTACK is too small (%d<400).\n", *parms.new_stack );
- retcode = FALSE;
- }
-
- if ( parms.new_image && parms.recolor )
- {
- printf("Error: Can't RECOLOR a NEWIMAGE.\n");
- retcode = FALSE;
- }
-
- if ( parms.new_tool || parms.old_tool_pat )
- {
- if ( parms.disks || parms.drawers || parms.tools || parms.garbage )
- {
- printf("Error: OLDTOOL and NEWTOOL not allowed with DISKS, DRAWERS, TOOLS, or GARBAGE.\n");
- retcode = FALSE;
- }
- }
-
- if ( parms.old_stack || parms.new_stack )
- {
- if ( parms.disks || parms.drawers || parms.garbage )
- {
- printf("Error: OLDSTACK and NEWSTACK not allowed with DISKS, DRAWERS, or GARBAGE.\n");
- retcode = FALSE;
- }
- }
-
- if ( parms.old_tool_pat )
- {
- if ( -1==ParsePatternNoCase( parms.old_tool_pat, old_tool_pat_parsed,MAXCHARS ) )
- {
- printf("Error: bad OLDTOOL pattern \"%s\".\n", parms.old_tool_pat );
- retcode = FALSE;
- }
- }
-
- if ( parms.file_pat )
- {
- if ( -1==ParsePatternNoCase( parms.file_pat, file_pat_parsed, MAXCHARS ) )
- {
- printf("Error: bad FILEPAT \"%s\".\n", parms.file_pat );
- retcode = FALSE;
- }
- }
-
- /***
- At this point, we have done all the parameter checking we can do
- without hitting the disk.
- ***/
-
- if ( parms.new_icon )
- {
- newicon = GetDiskObject( parms.new_icon );
- if ( ! newicon )
- {
- printf("Error: couldn't get NEWICON \"%s\".\n", parms.new_icon );
- retcode = FALSE;
- }
- }
-
- if ( parms.old_tool_pat || parms.new_tool )
- parms.projects = TRUE;
-
- if ( (parms.old_stack || parms.new_stack) &&
- !(parms.projects || parms.tools ) )
- {
- parms.projects = TRUE;
- parms.tools = TRUE;
- }
-
- if ( ! (parms.disks || parms.drawers || parms.projects || parms.tools || parms.garbage ) )
- parms.disks =
- parms.drawers =
- parms.projects =
- parms.tools =
- parms.garbage = TRUE;
-
- if ( parms.new_image )
- {
- strcpy( tmp_newimagename, parms.new_image );
- get_volume_name ( tmp_newimagename );
- newimage = GetDiskObject( tmp_newimagename );
- if ( ! newimage )
- {
- printf("Error: couldn't get NEWIMAGE \"%s\".\n", tmp_newimagename );
- retcode = FALSE;
- }
- }
-
- if ( parms.old_image )
- {
- strcpy( tmp_oldimagename, parms.old_image );
- get_volume_name ( tmp_oldimagename );
- oldimage = GetDiskObject( tmp_oldimagename );
- if ( ! oldimage )
- {
- printf("Error: couldn't get OLDIMAGE \"%s\".\n", tmp_oldimagename );
- retcode = FALSE;
- }
- }
-
- if ( ! (parms.unsnapshot || parms.recolor || parms.new_icon ||
- parms.new_image || parms.new_tool || (ULONG)parms.new_stack ) )
- {
- printf("Error: No actions specified.\n");
- retcode = FALSE;
- }
-
- if ( retcode == FALSE )
- scan_cleanup();
-
- return retcode;
- }
-
- void scan_cleanup( void )
- {
- if ( oldimage )
- {
- FreeDiskObject( oldimage );
- oldimage = NULL;
- }
- if ( newimage )
- {
- FreeDiskObject( newimage );
- newimage = NULL;
- }
- if ( newicon )
- {
- FreeDiskObject( newicon );
- newicon = NULL;
- }
- }
-
- static struct DiskObject tmp_DiskObject;
-
- BOOL mangle_diskobject( struct DiskObject *DO, char *filename )
- {
- BOOL retcode = TRUE;
-
- if ( parms.new_icon )
- tmp_DiskObject = *newicon;
- else
- tmp_DiskObject = *DO;
-
- if ( parms.new_stack )
- tmp_DiskObject.do_StackSize = *parms.new_stack;
-
- if ( parms.new_tool )
- tmp_DiskObject.do_DefaultTool = parms.new_tool;
-
- if ( parms.new_image )
- tmp_DiskObject.do_Gadget = newimage->do_Gadget;
-
- if ( parms.unsnapshot )
- {
- tmp_DiskObject.do_CurrentX =
- tmp_DiskObject.do_CurrentY = NO_ICON_POSITION;
- }
- if ( parms.recolor )
- {
- recolor( &tmp_DiskObject );
- }
-
- if ( ! parms.quiet && !parms.verbose) printf("%s",filename);
- if ( ! parms.test )
- {
- if (!PutDiskObject( filename, &tmp_DiskObject ))
- {
- if ( ! parms.quiet ) printf(" <------- CHANGE FAILED!");
- retcode = FALSE;
- }
- }
- if ( !parms.quiet || parms.verbose) printf("\n");
-
- if ( parms.recolor )
- {
- decolor( &tmp_DiskObject );
- }
-
- return retcode;
- }
-
- BOOL cmp_images( struct Image *im0, struct Image *im1 )
- {
- SHORT x,y,z,dy,x1;
- UWORD w0, w1;
- UWORD *b0, *b1;
- UWORD mask;
- UBYTE planepick0, planeonoff0, planepick1, planeonoff1;
-
- if ( im0->Width != im1->Width ||
- im0->Height != im1->Height ||
- im0->Depth != im1->Depth )
- {
- return FALSE;
- }
-
- planepick0 = im0->PlanePick;
- planepick1 = im1->PlanePick;
- planeonoff0 = im0->PlaneOnOff;
- planeonoff1 = im1->PlaneOnOff;
- b0 = im0->ImageData;
- b1 = im1->ImageData;
- dy = (im0->Width+15)/16;
- mask =~(0x0ffff>>(im0->Width%16));
- x1 = (im0->Width+15)/16;
-
- for ( z=0; z< im0->Depth; z++ )
- {
- for( y=0; y< im0->Height; y++ )
- for (x=0; x<x1; x++ )
- {
- if ( planepick0 & (1<<z) )
- w0 = b0[x+dy*y];
- else if ( planeonoff0 & (1<<z) )
- w0 = (USHORT)~0;
- else w0 = 0;
- if ( planepick1 & (1<<z) )
- w1 = b1[x+dy*y];
- else if ( planeonoff1 & (1<<z) )
- w1 = (USHORT)~0;
- else w1 = 0;
- if ( x == x1-1 )
- {
- w0 &= mask;
- w1 &= mask;
- }
- if ( w0 != w1 )
- {
- return FALSE;
- }
- }
- if ( planepick0 & (1<<z) )
- b0 += dy * im0->Height;
- if ( planepick1 & (1<<z) )
- b1 += dy * im1->Height;
- }
- return TRUE;
- }
-
- BOOL test_diskobject( struct DiskObject *DO, char *filename )
- {
- char *tmp_old_tool;
-
- if ( parms.verbose ) printf("Testing %s:", filename );
- // Check for all the selection criteria:
- // NAME, <type>, OLDSTACK, OLDTOOL, and OLDIMAGE
-
- // We already know that the name matches, so let's go on
- // and check the do_Type field.
-
- if ( newicon ) /* Only replace icons of the same type. */
- {
- if (newicon->do_Type != DO->do_Type )
- {
- if ( parms.verbose )
- printf(" wrong TYPE (was %s, needs %s).\n",
- do_TypeStr( DO->do_Type ),
- do_TypeStr( newicon->do_Type) );
- return FALSE;
- }
- }
- else
- {
- switch ( DO->do_Type )
- {
- case WBDISK : if ( ! parms.disks )
- {
- if ( parms.verbose ) printf(" wrong TYPE (DISK).\n");
- return FALSE;
- }
- break;
- case WBDRAWER : if ( ! parms.drawers )
- {
- if ( parms.verbose ) printf(" wrong TYPE (DRAWER).\n" );
- return FALSE;
- }
- break;
- case WBPROJECT : if ( ! parms.projects)
- {
- if ( parms.verbose ) printf(" wrong TYPE (PROJECT)\n");
- return FALSE;
- }
- break;
- case WBTOOL : if ( ! parms.tools )
- {
- if ( parms.verbose ) printf(" wrong TYPE (TOOL)\n");
- return FALSE;
- }
- break;
- case WBGARBAGE : if ( ! parms.garbage )
- {
- if ( parms.verbose ) printf(" wrong TYPE (GARBAGE)\n");
- return FALSE;
- }
- break;
- default : if ( ! parms.quiet ) printf(" unknown TYPE.\n");
- return FALSE;
- }
- }
-
- if ( parms.old_stack ) // We already think it is a project or a tool.
- {
- if ( (DO->do_Type != WBTOOL) && (DO->do_Type != WBPROJECT) )
- {
- printf("Error (internal): shouldn't be checking stack of a %s.\n", do_TypeStr(DO->do_Type) );
- return FALSE;
- }
- switch ( parms.old_stack_op )
- {
- case 1 :
- if ( DO->do_StackSize > parms.old_stack_val )
- {
- if ( parms.verbose ) printf(" stack (%d) too high.\n",DO->do_StackSize );
- return FALSE;
- }
- break;
- case 0 :
- if ( DO->do_StackSize != parms.old_stack_val )
- {
- if ( parms.verbose ) printf(" stack %d NE %d.\n",DO->do_StackSize,parms.old_stack_val );
- return FALSE;
- }
- break;
- case -1 :
- if ( DO->do_StackSize < parms.old_stack_val )
- {
- if ( parms.verbose ) printf(" stack (%d) too low.\n",DO->do_StackSize );
- return FALSE;
- }
- break;
- default :
- if ( parms.verbose ) printf("Error: Internal error wrt OLDSTACK.\n");
- return FALSE;
- break;
- }
- }
-
- // Next we see if the old_tool_pat matches.
- if ( parms.old_tool_pat )
- {
- if ( DO->do_DefaultTool )
- tmp_old_tool = DO->do_DefaultTool;
- else
- tmp_old_tool = "";
-
- if (DO->do_Type != WBPROJECT )
- {
- if ( parms.verbose ) printf("Not a PROJECT.\n" );
- return FALSE; // Old tool only checked for Projects.
- }
-
- if ( !MatchPatternNoCase( old_tool_pat_parsed, tmp_old_tool ) )
- {
- if ( parms.verbose ) printf(" DEFAULT TOOL (%s) doesn't match OLDTOOL pattern.\n", tmp_old_tool );
- return FALSE; // Old tool only checked for Projects.
- }
- }
-
- // So far so good. Now we compare the images.
- if ( oldimage )
- {
- if ( ! cmp_images( (struct Image *)DO ->do_Gadget.GadgetRender,
- (struct Image *)oldimage->do_Gadget.GadgetRender ) )
- {
- if ( parms.verbose ) printf(" OLDIMAGE doesn't match.\n");
- return FALSE;
- }
- }
-
- // If we got this far, then the icon is ripe for changing.
-
- if ( parms.verbose ) printf(" selected.");
- return TRUE;
- }
-
- BOOL is_a_dot_info( char *fn )
- {
- short i,j;
-
- i=strlen( fn );
- if ( i < 6 ) return FALSE;
- for (j=0; j<5; j++)
- if ( ".info"[j] != tolower( fn[i-5+j] ) ) return FALSE;
- fn[i-5] = '\0';
- return TRUE;
- }
-
- int scan_directory( char *dirname )
- {
- struct FileLock *lock;
- struct FileInfoBlock *fib;
- char *filename;
- long retcode;
- struct DiskObject *diskobj;
-
- filename = AllocMem( MAXCHARS, MEMF_CLEAR );
- if (filename == NULL) {
- retcode = ALLOCATE_FAILURE;
- goto SD_DIE1;
- }
-
- fib = AllocMem( sizeof(struct FileInfoBlock), MEMF_CLEAR);
- if (fib == NULL) {
- retcode = ALLOCATE_FAILURE;
- goto SD_DIE2;
- }
-
- lock = (struct FileLock *) Lock(dirname,ACCESS_READ);
- if (lock == NULL) {
- retcode = BAD_FILE_NAME;
- goto SD_DIE3;
- }
-
- retcode = Examine( (BPTR)lock, fib );
- if (retcode == 0) {
- retcode = BAD_FILE_NAME;
- goto SD_DIE4;
- }
-
- if (fib->fib_DirEntryType < 0) { /* it's a file */
- retcode = INVALID_DIR_NAME;
- goto SD_DIE5;
- }
-
- /*!!! We have to do the ExNext once outside of the while loop
- and the rest inside the loop but before we mangle the
- diskobj so when we do the PutDiskObject() it will replace
- the file we examined before--NOT the one the current fib
- references. Whew! What a joy to figure this one out.
- !!!*/
-
- retcode = ExNext((BPTR)lock, fib );
-
- while ( retcode && !stop_check())
- {
- strcpy(filename,dirname);
- if ( strlen(filename) > 0 && filename[ strlen(filename)-1 ] != ':' )
- strcat(filename,"/");
- strcat( filename, fib->fib_FileName );
-
- if (fib->fib_DirEntryType > 0 && parms.all && !stop_check()) /* it's a directory */
- {
- scan_directory( filename );
- }
-
- /* Gotta get the next files fib so the PutDiskObject() doesn't
- yank the file we are examining out from under us.
- */
-
- retcode = ExNext((BPTR)lock, fib );
-
- /* Now we've ExNext()ed the next file, but we can still play
- * with the last one's icon without messing up our NEXT ExNext().
- */
-
- if ( is_a_dot_info( filename ) ) /* chops off ".info" and returns TRUE */
- { /* ELSE return FALSE if it didn't end w/ ".info" */
- if ( !parms.file_pat ||
- MatchPatternNoCase( file_pat_parsed, FilePart(filename) ) )
- {
-
- if ( (diskobj = GetDiskObject( filename )) )
- {
- if (test_diskobject( diskobj, filename ) )
- mangle_diskobject( diskobj, filename );
- FreeDiskObject( diskobj );
- }
- }
- }
- } /* end of while (ExNext())... */
-
- retcode = OK;
- SD_DIE5: ;
- SD_DIE4: UnLock((BPTR)lock);
- SD_DIE3: FreeMem( fib, sizeof(struct FileInfoBlock) );
- SD_DIE2: FreeMem( filename, MAXCHARS );
- SD_DIE1: return( retcode );
- }
-
- int get_volume_name( char *dirname )
- { /* expands the string <dirname> to the full path name. */
- struct FileLock *lock, *tmplock;
- struct FileInfoBlock *fib;
- char *volname;
- long retcode;
-
- volname = AllocMem( MAXCHARS, MEMF_CLEAR );
- if (volname == NULL) {
- retcode = ALLOCATE_FAILURE;
- goto GVN_DIE1;
- }
-
- fib = AllocMem( sizeof(struct FileInfoBlock), MEMF_CLEAR);
- if (fib == NULL) {
- retcode = ALLOCATE_FAILURE;
- goto GVN_DIE2;
- }
-
- lock = (struct FileLock *) Lock(dirname,ACCESS_READ);
- if (lock == NULL) {
- retcode = BAD_FILE_NAME;
- goto GVN_DIE3;
- }
-
- retcode = Examine( (BPTR)lock, fib );
- if (retcode == 0) {
- retcode = BAD_FILE_NAME;
- goto GVN_DIE4;
- }
-
- // if (fib->fib_DirEntryType < 0) { /* it's a file */
- // retcode = INVALID_DIR_NAME;
- // goto GVN_DIE5;
- // }
-
- strcpy(volname,fib->fib_FileName);
- dirname[0] = '\0';
-
- while ( tmplock = (struct FileLock *)ParentDir( (BPTR)lock) ) {
- UnLock((BPTR)lock);
- lock = tmplock;
- retcode = Examine( (BPTR)lock, fib );
- if (retcode == 0) {
- retcode = BAD_FILE_NAME;
- goto GVN_DIE4;
- }
- if (dirname[0]) {
- strcat(volname,"/");
- strcat(volname,dirname);
- }
- strcpy(dirname,volname);
- strcpy(volname,fib->fib_FileName );
- }
-
- strcat(volname,":");
- strcat(volname,dirname);
- strcpy(dirname,volname);
-
- if ( ! parms.quiet ) printf("Examining \"%s\".\n",volname);
-
- retcode = OK;
- GVN_DIE5: ;
- GVN_DIE4: UnLock((BPTR)lock);
- GVN_DIE3: FreeMem( fib, sizeof(struct FileInfoBlock) );
- GVN_DIE2: FreeMem( volname, MAXCHARS );
- GVN_DIE1: return( retcode );
- }
-
-